#ifndef __LIST_H__
#define __LIST_H__

struct list_head {
  struct list_head *prev, *next;
};

#define LIST_ENTRY(ptr, type, member)	\
  ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

#define LIST_INIT(ptr) do { (ptr)->prev = (ptr)->next = (ptr); } while (0)

static inline void __list_add(struct list_head *prev, 
    struct list_head *next, struct list_head *newval) {
  prev->next = newval;
  newval->prev = prev;
  newval->next = next;
  next->prev = newval;
}

static inline void list_add(struct list_head *head, 
    struct list_head *newval) {
  __list_add(head, head->next, newval);
}

static inline void list_add_tail(struct list_head *head, 
    struct list_head *newval) {
  __list_add(head->prev, head, newval);
}

static inline void __list_del(struct list_head *prev, 
    struct list_head *next) {
  prev->next = next;
  next->prev = prev;
}

static inline void list_del(struct list_head *entry) {
  __list_del(entry->prev, entry->next);
  entry->prev = entry->next = NULL;
}

static inline int list_empty(struct list_head *head) {
  return head->next == head;
}

static inline struct list_head *list_next(struct list_head *entry) {
  return entry->next;
}

static inline struct list_head *list_prev(struct list_head *entry) {
  return entry->prev;
}

#endif